package com.bit.cfdi.web.vm.negocio;

import java.io.IOException;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.zkoss.bind.BindContext;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.image.Image;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Messagebox;

import com.bit.cfdi.web.constants.CFDIConstants;
import com.bit.cfdi.web.domain.Negocio;
import com.bit.cfdi.web.services.NegocioService;
import com.bit.cfdi.web.session.SessionUtils;
import com.bit.cfdi.web.utils.ByteUtils;
import com.bit.cfdi.web.utils.ImageUtils;

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class ConfigurarImagenViewModel {
	
	private Logger log = LogManager.getLogger(this.getClass().getName());
	
	//Spring variables
	@WireVariable
	private SessionUtils sessionUtils;
	@WireVariable
	private NegocioService negocioService;
	
	private Image negImage;
	
	private byte[] imageInBytes;
	private String imageFormat;
	
	@Init
	public void init() {
		retrieveInitialInfo();
	}
	
	//Getters - Setters
	public Image getNegImage() {
		return negImage;
	}
	
	//Local commands
	@Command @NotifyChange({"negImage"})
	public void uploadBusinessImage(@ContextParam(ContextType.BIND_CONTEXT) 
			BindContext ctx) {
		
		UploadEvent event = (UploadEvent) ctx.getTriggerEvent();
		Media mediaObj = event.getMedia();
		if(!(mediaObj instanceof Image)) {
			showImageNotSupported();
			return;
		}
		Image imageRetrieved = (Image) mediaObj;
		if(!CFDIConstants.SUPPORTED_IMAGES.contains(
				imageRetrieved.getFormat())) {
			showImageNotSupported();
			return;
		}
		try {
			imageInBytes = imageRetrieved.getByteData();
			imageFormat = imageRetrieved.getFormat();
			negImage = ImageUtils.scaleToSize(imageInBytes, 170, 85, 
					imageFormat).getContent();
		} catch (IOException e) {
			log.error("Couldn't create image thumnail "+e.getMessage());
			negImage = getDefaultBusinessImage();
		}
		
	}
	
	@Command
	public void performSave() {
		if(imageInBytes == null || imageFormat == null) {
			return;
		}
		Negocio neg = (Negocio) sessionUtils.getFromSession(
				SessionUtils.NEGOCIO);
		neg.setLogoNegocio(ByteUtils.toByteWrapper(imageInBytes));
		neg.setFormatoLogo(imageFormat);
		negocioService.save(neg);
		
		Messagebox.show("Imagen de negocio actualizada");
		
		//Updating nav negocio
		BindUtils.postGlobalCommand(null, null, "negocioRefreshNegocioInfo", 
				null);
	}
	
	@Command @NotifyChange({"imageInBytes", "imageFormat", "negImage"})
	public void performCancel() {
		retrieveInitialInfo();
	}
	
	//private methods
	private void retrieveInitialInfo() {
		imageInBytes = null;
		imageFormat = null;
		Negocio neg = (Negocio) sessionUtils.getFromSession(
				SessionUtils.NEGOCIO);
		byte[] image = ByteUtils.toByteNative(neg.getLogoNegocio());
		String format = neg.getFormatoLogo();
		if(image == null || format == null || 
				!CFDIConstants.SUPPORTED_IMAGES.contains(format)) {
			negImage = getDefaultBusinessImage();
		}
		else {
			try {
				negImage = ImageUtils.scaleToSize(image, 170, 85, format)
						.getContent();
			} catch (IOException e) {
				log.error("Business image couldn't be retrieved "+
			e.getMessage());
				negImage = getDefaultBusinessImage();
			}
		}
	}
	
	private Image getDefaultBusinessImage() {
		try {
			return ImageUtils.getImageFromClassResource(
					"negocio/default_business.png");
		} catch (IOException e) {
			log.error("Default business image couldn't be created "+
					e.getMessage());
			return null;
		}
	}
	
	private void showImageNotSupported() {
		Messagebox.show("Imagen no soportada\n" +
				"formatos soportados (jpg, png, gif)");
	}

}
